package com.cjb.cloudsystem.task;

import com.cjb.cloudfabric.service.OperateFabricService;
import com.cjb.cloudsystem.entity.DeviceStatus;
import com.cjb.cloudsystem.entity.SysParams;
import com.cjb.cloudsystem.entity.TraceabilityData;
import com.cjb.cloudsystem.service.DeviceStatusService;
import com.cjb.cloudsystem.service.SysParamsService;
import com.cjb.cloudsystem.service.TraceabilityDataService;
import com.cjb.cloudsystem.vo.SysParamsVO;
import com.cjb.common.common.cache.RedisCache;
import com.cjb.common.util.Common;
import com.cjb.common.util.Constant;
import com.cjb.common.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @Author chenjinbin
 * @Package IntelliJ IDEA
 * @Class taskMain
 * @Date 2023-11-10 上午12:37
 */
@Component
@Slf4j
public class DeviceCollectTask implements SchedulingConfigurer {

    /**
     * 注入值
     */
    @Value("${encrypt.alg}")
    private String alg;
    @Value("${encrypt.secret}")
    private String secret;
    /**
     * 注入redis服务类
     */
    @Autowired
    private RedisCache redisCache;
    /**
     * 注入设备服务
     */
    @Autowired
    private DeviceStatusService deviceStatusService;

    /**
     * 区块数据查询
     */
    @Autowired
    private OperateFabricService operateFabricService;
    /**
     * 区块数据查询
     */
    @Autowired
    private TraceabilityDataService traceabilityDataService;
    /**
     * 参数收集服务类
     */
    @Autowired
    private SysParamsService sysParamsService;
    @Autowired
    private ThreadPoolTaskScheduler taskScheduler;

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskScheduler);
        log.info("定时任务的执行");
        taskRegistrar.addTriggerTask(
                //设备 历史数据存储任务
                () -> {
                    // Your task logic here...
                    log.info("打印这段任务的执行，历史数据的收集");
                    //获取缓存最新的信息(如果有)
                    String jsonMsg = (String) redisCache.hGet("message", "deviceStatus");
                    if (Common.isNotEmpty(jsonMsg)) {
                        //存储到数据库
                        DeviceStatus deviceStatus = JsonUtils.parseObject(jsonMsg, DeviceStatus.class);
                        //入库
                        if (Common.isNotEmpty(deviceStatus)){

                            com.cjb.cloudfabric.entity.DeviceStatus fabricDevice = new com.cjb.cloudfabric.entity.DeviceStatus();
                            try {
                                Common.copyNonNullProperties(deviceStatus,fabricDevice);
                            } catch (Throwable e) {

                            }
                            TraceabilityData traceabilityData = new TraceabilityData();
                            try {
                                operateFabricService.SubmitDeviceData(fabricDevice);
                                //溯源成功 溯源成功记录
                                traceabilityData.setDeviceId(deviceStatus.getDeviceId());
                                traceabilityData.setEncryAlg(alg);
                                traceabilityData.setEncrySecret(secret);
                                //0 成功 1失败
                                traceabilityData.setIsTrue(0);
                                traceabilityData.setRemark("上链成功");
                                traceabilityData.setUserId("1");
                                traceabilityData.setPreviewData(JsonUtils.toJsonString(deviceStatus));
                                traceabilityDataService.save(traceabilityData);
                                //数据入库
                                deviceStatusService.save(deviceStatus);
                            } catch (Exception e) {
                                log.error("上链失败");
                                //溯源失败 记录
                                traceabilityData.setIsTrue(1);
                                traceabilityData.setRemark("未知原因上链失败");
                                traceabilityDataService.save(traceabilityData);
                            }
                        }
                    }
                },
                // 触发
                triggerContext -> {
                    // 您可以从数据库中获取cron表达式
                    String cron = changeCron(Integer.valueOf(getCron("DEVICE_COLLECT_TIME")));
                    log.info("打印这段的触发");
                    return new CronTrigger(cron).nextExecutionTime(triggerContext).toInstant();
                }
        );
        //区块数据同步
        taskRegistrar.addTriggerTask(
                () -> {
                    //区块数据查询
                    String asset = null;
                    try {
                        asset = operateFabricService.QueryAllAsset();
                    } catch (Exception e) {
                        String errMsg = "查询出现错误" + e.getMessage();
                    }
                    //sql数据查询
                    List<DeviceStatus> deviceStatusList = deviceStatusService.returnAllData();

                    //数据归一 统计有意义的数据
                    if (Common.isNotEmptyVales(asset, deviceStatusList)) {
                        log.info("打印这两个数据");
                    }
                    //生成日志

                },
                triggerContext -> {
                    String cron = changeCron(Integer.valueOf(getCron("BLOCK_SQL_SYNC_TIME")));
                    log.info("打印这段的触发");
                    return new CronTrigger(cron).nextExecutionTime(triggerContext).toInstant();
                }
        );
    }

    /**
     * cron表达式转化 --分钟
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    private String changeCron(Integer minute) {
        return "0 0/" + minute.toString() + " * * * *";
    }

    /**
     * 数据读取 -- 历史数据收集的时间
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    private String getCron(String key) {
        //缓存
        log.info("打印這個key: {}",JsonUtils.toJsonString(key));
        String deviceCollectTime = (String) redisCache.hGet(Constant.SYSTEM_PARAMS_KEY, key);
        if (Common.isNotEmpty(deviceCollectTime)) {
            log.info("打印缓存的时间 {}", JsonUtils.toJsonString(deviceCollectTime));
            return deviceCollectTime;
        }
        //数据库
        SysParamsVO sysParams = new SysParamsVO();
        sysParams.setParamKey(key);
        List<SysParams> params = sysParamsService.queryBySysParams(sysParams);
        log.info("打印数据库的时间 {}", JsonUtils.toJsonString(params));
        if (Common.isNotEmpty(params) && Common.isNotEmpty(params.get(0).getParamValue())) {
            //数据进缓存
            redisCache.hSet(Constant.SYSTEM_PARAMS_KEY, key, params.get(0).getParamValue());
             return params.get(0).getParamValue();
        }
        else {
            return "30";
        }
    }
}
